////////////////////////////////////////////////////////////////
// Screen_GL.cpp
// System Set Implementation Template
//
////////////////////////////////////////////////////////////////

#include "Screen_GL.h"
#include <iostream>
#include <sstream>
using namespace std;
//SCREEN_GL////////////////////////////////////////////////
// INIT ///////////////////////////////////////////////////
// creates the OpenGl Window
//
///////////////////////////////////////////////////////////
bool Screen_GL::Init(void)
{
   if (InitGLScene() == false)
   	{
      printf("OpenGL states not set up!");
      return false;
      }/**/

	return true;
}

//SCREEN_GL////////////////////////////////////////////////
// SHAPE //////////////////////////////////////////////////
// sets up the viewport size and the projection matrix
//
///////////////////////////////////////////////////////////
void Screen_GL::Shape(uint16 pw, uint16 ph)
{
	glViewport     ( 0, 0, pw, ph );
   glMatrixMode   ( GL_PROJECTION );
   glLoadIdentity ( );
   if ( ph==0 )
      gluPerspective ( 80, ( float ) pw, 0.1f, 1000.0f );
   else
      gluPerspective ( 80, ( float ) pw / ( float ) ph, 0.1f, 1000.0f );
   glMatrixMode   ( GL_MODELVIEW );
   glLoadIdentity ( );
}

//SCREEN_GL////////////////////////////////////////////////
// LOAD ///////////////////////////////////////////////////
// Loads Gfx based resources
//
///////////////////////////////////////////////////////////
bool Screen_GL::Load(uchar pType, std::string &pFileName)
{
	bool temp;

   switch(pType) {
   	case LOAD_TXT: temp = _TxtMgr.Load(pFileName); break;
   	};
	return temp;
};

//SCREEN_GL////////////////////////////////////////////////
// UNLOAD /////////////////////////////////////////////////
// UnLoads Gfx based resources
//
///////////////////////////////////////////////////////////
bool Screen_GL::Unload(uchar pType, uint16 pIndex)
{
	bool temp;

   switch(pType) {
   	case LOAD_TXT: temp = _TxtMgr.Unload(pIndex); break;
   	};
	return temp;
};

//SCREEN_GL////////////////////////////////////////////////
// RESET //////////////////////////////////////////////////
// Reloads textures in materials
// Calculate back font display lists
///////////////////////////////////////////////////////////
void Screen_GL::Reset(void)
{
   _TxtMgr.Reset();
}

//SCREEN_GL////////////////////////////////////////////////
// GETRESSSIZE ////////////////////////////////////////////
// Returns the size of the resource pool.
// Used to distinguish GUI resources from scenario resources
///////////////////////////////////////////////////////////
uint16 Screen_GL::GetRessSize(uchar pType)
{
	uint16 temp = 0;
   switch(pType) {
   	case LOAD_TXT: temp = _TxtMgr.Size(); break;
   	};
   return temp;
};

//SCREEN_GL////////////////////////////////////////////////
// SETFONT ////////////////////////////////////////////////
// Selects a glut Font
//
///////////////////////////////////////////////////////////
void Screen_GL::SetFont(void* pFont)
{
	if (pFont == NULL)
   	_cFont = GLUT_BITMAP_TIMES_ROMAN_24;

   _cFont = pFont;
   if (_cFont<(void *)0x0002)
      BitmapFont = false;
   else
      BitmapFont = true;
/*   switch (reinterpret_cast<uint32>(_cFont)) {
   	case GLUT_BITMAP_9_BY_15:
   	case GLUT_BITMAP_8_BY_13:
   	case GLUT_BITMAP_TIMES_ROMAN_10:
   	case GLUT_BITMAP_TIMES_ROMAN_24:
	#if (GLUT_API_VERSION >= 3)
		case GLUT_BITMAP_HELVETICA_10:
		case GLUT_BITMAP_HELVETICA_12:
		case GLUT_BITMAP_HELVETICA_18:
	#endif
      	BitmapFont = true; break;
      case GLUT_STROKE_ROMAN:
      case GLUT_STROKE_MONO_ROMAN:
      	BitmapFont = false; break;
   	};/**/

}

//SCREEN_GL////////////////////////////////////////////////
// PRINT //////////////////////////////////////////////////
// Prints a text at Vector pos
//
///////////////////////////////////////////////////////////
void Screen_GL::Print(std::string pText, Frm::Vertex pV)
{
	if(!_Gfx2D) return;

   glRasterPos2f(pV[0],pV[1]);// Position The Text (0,0 - Bottom Left)
   if (BitmapFont)
   	{
      glRasterPos2f(pV[0],pV[1]);// Position The Text (0,0 - Bottom Left)
	   for (int i = 0; i < pText.size(); i++)
			glutBitmapCharacter(_cFont, pText[i]);
      }
   else
   	{
      glPushMatrix();
	   glTranslatef(pV[0],pV[1],pV[2]);
   	for (int i = 0; i < pText.size(); i++)
         glutStrokeCharacter(_cFont, pText[i]);
      glPopMatrix();
      }
}

//SCREEN_GL////////////////////////////////////////////////
// PRINTFPS ///////////////////////////////////////////////
// Prints the nb frames per second
//
///////////////////////////////////////////////////////////
void Screen_GL::PrintFPS(uint32 pDelta)
{
   Frm::Vertex vv;
   ostringstream ostr;
   glBindTexture(GL_TEXTURE_2D, 0);

   if(pDelta == 0) return;
   ostr << (1000 / pDelta) << " FPS" << ends;
   vv = Frm::Set3(0.0f, 0.0f, 0.0f);
   glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
   Print(ostr.str(), vv);
   SetColor(255, 255, 255);

};

//SCREEN_GL////////////////////////////////////////////////
// PRINTFPS ///////////////////////////////////////////////
// Prints the nb frames per second
//
///////////////////////////////////////////////////////////
void Screen_GL::SetMaterial(Frm::Material* &pMaterial)
{
	glColor4fv(pMaterial->_FaceColor.data);
   if (pMaterial->_TextID != TXTMGR_NOTEXTURE)
   	SelectTexture(pMaterial->_TextID);
   else
   	glBindTexture(GL_TEXTURE_2D, 0);
}

//SCREEN_GL////////////////////////////////////////////////
// GFX2D //////////////////////////////////////////////////
// Switches to 2d ortho projection mode.
// Use in conjunction with Gfx3d()
///////////////////////////////////////////////////////////
void Screen_GL::TwoD(void)
{
   if (_Gfx2D)
   	return;

   int vPort[4];
   glGetIntegerv(GL_VIEWPORT, vPort);

	glMatrixMode(GL_PROJECTION);
	glPushMatrix();									// Store The Projection Matrix
	glLoadIdentity();								   // Reset The Projection Matrix
   glOrtho(0, vPort[2], 0, vPort[3], -1, 1); // Set Up An Ortho Screen
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();									// Store old Modelview Matrix
	glLoadIdentity();								   // Reset The Modelview Matrix
   _Gfx2D = true;
}


//SCREEN_GL////////////////////////////////////////////////
// GFX3D //////////////////////////////////////////////////
// Switches out of 2d ortho projection mode.
// Use in conjunction with Gfx2d()
///////////////////////////////////////////////////////////
void Screen_GL::ThreeD(void)
{
	if(!_Gfx2D)
   	return;
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();									// Restore old Projection Matrix
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();									// Restore old Projection Matrix
   _Gfx2D = false;
}

//SCREEN_GL////////////////////////////////////////////////
// CLEARSCREEN ////////////////////////////////////////////
// Clears the screen
//
///////////////////////////////////////////////////////////
void Screen_GL::ClearScreen(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear The Screen And The Depth Buffer
	glLoadIdentity(); //Reset The Current Modelview Matrix
}

//SCREEN_GL////////////////////////////////////////////////
// INITGLSCENE ////////////////////////////////////////////
// Initializes the scene
//
///////////////////////////////////////////////////////////
bool Screen_GL::InitGLScene(GLvoid)
{
	glShadeModel(GL_SMOOTH); // Enables Smooth Shading

	glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //Black Background
	glClearDepth(1.0f); //Depth Buffer Setup
	glEnable(GL_DEPTH_TEST); // EnablesDepth Testing
	glDepthFunc(GL_LESS); //The Type Of Depth Test To Do
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //Really Nice Perspective Calculations
   glEnable(GL_BLEND);/**/
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   glEnable(GL_TEXTURE_2D);
   glEnable(GL_CULL_FACE);
   glCullFace(GL_BACK);
   _Gfx2D = false;

	return true; //Initialization Went OK
}


